#ifndef DW_GRAPHICS_BOUNDINGVOLUME_H
#	define DW_GRAPHICS_BOUNDINGVOLUME_H

namespace dw {
	namespace graphics {

using maths::Point3f;
using maths::Vector3f;
using maths::Matrix4f;
using maths::Quaternionf;
using maths::Ray;
using maths::Cuboid;
using maths::Sphere;

class IBoundingVolume
{
public:

	virtual bool intersects(const Point3f& p) const = 0;

	virtual void transform(const Matrix4f& m) = 0;

};

class BoundingBox : public IBoundingVolume, public Cuboid
{
public:

	BoundingBox();

	BoundingBox(const Point3f& center, const float width, const float height, const float depth);

	BoundingBox(const Point3f& center, const Vector3f& size);

	BoundingBox(const Point3f& min, const Point3f& max);

	~BoundingBox();

public:

	virtual void getVertices(std::vector< Point3f >& points) const = 0;

};

class AxisAlignedBoundingBox : public BoundingBox
{
public:

	AxisAlignedBoundingBox();

	AxisAlignedBoundingBox(const Point3f& center, const float width, const float height, const float depth);

	AxisAlignedBoundingBox(const Point3f& center, const Vector3f& size);

	AxisAlignedBoundingBox(const Point3f& min, const Point3f& max);

	~AxisAlignedBoundingBox();

public:

	virtual void getVertices(std::vector< Point3f >& points) const ;



	virtual bool intersects(const Point3f& p) const ;

	virtual bool intersects(const AxisAlignedBoundingBox& aabb) const ;

	virtual void transform(const Matrix4f& m);

	virtual void merge(const AxisAlignedBoundingBox& aabb);

};

class OrientedBoundingBox : public BoundingBox
{
public:

	OrientedBoundingBox();

	~OrientedBoundingBox();

public:

	virtual void getVertices(std::vector< Point3f >& points) const ;



	virtual bool intersects(const Point3f& p) const ;

	virtual void transform(const Matrix4f& m);

protected:

	Quaternionf _orientation;

};


class BoundingSphere : public IBoundingVolume, public Sphere
{
public:

	BoundingSphere();

	~BoundingSphere();

public:

	bool intersects(const Vector3f& p) const ;

	void transform(const Matrix4f& m);

};

typedef AxisAlignedBoundingBox AABBox;
typedef OrientedBoundingBox OBBox;
typedef BoundingSphere BSphere;

	} // namespace graphics
} // namespace dw

#endif // !DW_GRAPHICS_BOUNDINGVOLUME_H
